package com.bblocks.standard.controller;


import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import com.google.common.collect.Lists;
import com.bblocks.common.BaseController;
import com.bblocks.common.auth.IgnoreLog;
import com.bblocks.standard.entity.SysParam;
import com.bblocks.standard.service.SysParamService;
/*import com.bblocks.user.entity.vo.BaseUserInfoVo;
import com.bblocks.user.entity.vo.UserInfoViewVo;
import com.bblocks.user.feign.UserFeign;*/
import com.bblocks.util.KryoRedisSerializer;
import com.bblocks.util.R;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.util.Assert;
import org.springframework.util.StopWatch;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * 系统配置(SysParam)表控制层
 *
 * @author makejava
 * @since 2021-10-29 13:57:44
 */
@Slf4j
@Tag(description = "sysParam", name = "系统参数操作")
@RestController
@RequestMapping("/system/sysParam")
public class SysParamController extends BaseController {
	private static final boolean userLocalCache = true;
	public static final Cache<String, Object> cache = Caffeine.newBuilder()
			.expireAfterWrite(10, TimeUnit.MINUTES)
			.maximumSize(10_000)
			.build();

	/**
     * 服务对象
     */
    @Resource
    private SysParamService sysParamService;
	@Qualifier("KryoRedisSerializer")
   	//@Autowired
    //private KryoRedisSerializerConfig kryoRedisSerializerConfig;
	KryoRedisSerializer<Object> kryoRedisSerializer = new KryoRedisSerializer<>(Object.class);



	//@IgnoreLog(0)
	@Operation(summary = "提取系统参数", description = "提取系统参数")
    @GetMapping("/{paramName}")
    public R<SysParam> selectOne(@PathVariable String paramName) {
        Assert.notNull(paramName,"paramName参数不能为空！");
        StopWatch stopWatch = new StopWatch();
		stopWatch.start("data");
        SysParam param = this.sysParamService.getByName(paramName);

		stopWatch.stop();
        log.info("耗時：{}",stopWatch.getTotalTimeNanos());
        return R.ok(param) ;
    }

	@Operation(summary = "提取系统参数（多个)", description = "")
	@GetMapping("/{paramName}/{count}")
	public R<List<SysParam>> selectOnes(@PathVariable String paramName,@PathVariable Integer count) {
		Assert.notNull(paramName,"paramName参数不能为空！");
		StopWatch stopWatch = new StopWatch();
		stopWatch.start("data");
		SysParam param = this.sysParamService.getByName(paramName);

		List<SysParam> result = Lists.newArrayListWithExpectedSize(count);
		if(param != null){
			for(int i = 0; i < count; i++){
				SysParam one =	SysParam.builder().build();
				BeanUtils.copyProperties(param,one);
				result.add(one);
			}
		}else
			result = Lists.newArrayListWithExpectedSize(0);
		stopWatch.stop();
		log.info("耗時：{}",stopWatch.getTotalTimeNanos());

		return R.ok(result) ;
	}

	@IgnoreLog(3)
    @Operation(summary = "提取系统参数值", description = "原则只返回yz的且系统可见的")
    @GetMapping("/paramValue/{paramName}")
    public R<String> selectOneValue(@PathVariable String paramName) {
        Assert.notNull(paramName,"paramName参数不能为空！");
		StopWatch stopWatch = new StopWatch();
        SysParam param = this.sysParamService.getByName(paramName);
		stopWatch.start("data");

        if(param != null){
            if(! SysParamService.PARAM_PRE_YZ.equalsIgnoreCase(param.getGroupId())
                    ||param.getIsSystem() == 1)
                param = null;
        }
		stopWatch.stop();
		log.info("耗時：{}",stopWatch.getTotalTimeNanos());
        if(param != null)
             return R.ok(param.getValue()) ;
        else
            return R.ok(null) ;
    }


	@IgnoreLog(3)
    @Operation(summary = "提取系统参数（二级缓存）", description = "原则只返回yz的且系统可见的")
	@GetMapping("/2/{paramName}")
	public R<SysParam> selectOne2(@PathVariable String paramName) {
		Assert.notNull(paramName,"paramName参数不能为空！");
		StopWatch stopWatch = new StopWatch();
		stopWatch.start("data");

		String key = paramName;
		SysParam param = (SysParam)cache.getIfPresent(key);
		if(param == null){
			param = this.sysParamService.getByName(paramName);
			if(param != null)
				cache.put(key,param);
		}

		stopWatch.stop();
		log.info("耗時：{}",stopWatch.getTotalTimeNanos());
		return R.ok(param) ;
	}

	@IgnoreLog(3)
    @Operation(summary = "提取系统参数值（二级缓存）", description = "原则只返回yz的且系统可见的")
	@GetMapping("/paramValue2/{paramName}")
	public R<String> selectOneValue2(@PathVariable String paramName) {
		Assert.notNull(paramName,"paramName参数不能为空！");
		StopWatch stopWatch = new StopWatch();
		stopWatch.start("data");

		String key = paramName;
		SysParam param = (SysParam)cache.getIfPresent(key);
		if(param == null){
			param = this.sysParamService.getByName(paramName);
			if(param != null)
				cache.put(key,param);
		}

		stopWatch.stop();
		log.info("耗時：{}",stopWatch.getTotalTimeNanos());
		if(param != null)
			return R.ok(param.getValue()) ;
		else
			return R.ok(null) ;
	}

    //@Inner
    @Operation(summary = "系统参数值提取-内部", description = "内部用"
		,parameters = {
			@Parameter(name = "paramName", description = "参数key"),
			@Parameter(name = "defaultValue", description = "默认值"),
		}
	)
    @GetMapping("/valueInner/{paramName}")
    public R<String> selectOneValueInnner(@PathVariable String paramName, String defaultValue) {
        Assert.notNull(paramName,"paramName参数不能为空！");

        String paramValue = null;
		String key = paramName+"_value";
		if(userLocalCache){
			paramValue = (String)cache.getIfPresent(key);
		}

		if(paramValue == null) {
			paramValue = this.sysParamService.getByNameValue(paramName,defaultValue);
			if(userLocalCache && paramValue != null)
				cache.put(key,paramValue);
		}

        return R.ok(paramValue);
    }

	//@Inner
	@Operation(summary = "系统参数提取-内部", description = "内部用"
			,parameters = {
				@Parameter(name = "paramName", description = "参数key",in = ParameterIn.PATH),
			}
	)
	@GetMapping("/objInner/{paramName}")
	public R<SysParam> selectOneInnner(@PathVariable String paramName) {
		Assert.notNull(paramName,"paramName参数不能为空！");

		String key = paramName;
		SysParam param = null;
		if(userLocalCache){
			param = (SysParam)cache.getIfPresent(key);
		}

		if(param == null) {
			param = this.sysParamService.getByName(paramName);
			if(userLocalCache && param != null)
				cache.put(key,param);
		}
		return R.ok(param);
	}

	//@Inner
	@Operation(summary = "系统参数们提取-内部", description = "内部用"
			,parameters = {
			@Parameter(name = "paramName", description = "参数key",in = ParameterIn.PATH),
			@Parameter(name = "count", description = "数量",in = ParameterIn.PATH),
			}
	)
	@GetMapping("/objsInner/{paramName}/{count}")
	public R<List<SysParam>> selectOnesInnner(@PathVariable String paramName,@PathVariable Integer count) {
		Assert.notNull(paramName,"paramName参数不能为空！");

		String key = paramName+"&"+count;
		List<SysParam> result;
		if(userLocalCache){
			result = (List<SysParam>)cache.getIfPresent(key);
		}

		if(result == null) {
			result = selects(paramName, count);
			if (userLocalCache) {
				cache.put(key, result);
			}
		}
		return R.ok(result);
	}


	private List<SysParam> selects( String paramName, Integer count) {
		if(count == null || count<=0)
			count = 1;
		//SysParam param = this.sysParamService.getByName(paramName);
		String key = paramName;
		SysParam param = null;
		if(userLocalCache){
			param = (SysParam)cache.getIfPresent(key);
		}
		if(param == null) {
			param = this.sysParamService.getByName(paramName);
			if(userLocalCache && param != null)
				cache.put(key,param);
		}

		List<SysParam> result = Lists.newArrayListWithExpectedSize(count);
		if(param != null){
			for(int i = 0; i < count; i++){
				SysParam one =	SysParam.builder().build();
				BeanUtils.copyProperties(param,one);
				result.add(one);
			}
		}else
			result = Lists.newArrayListWithExpectedSize(0);

		return result ;
	}




	private Map<Integer,String> getDatas(){
		Map<Integer,String> result = new HashMap<>();
		//赵钱孙李,周吴郑王
		result.put(1, "zhao");
		result.put(2, "钱");
		result.put(3, "孙");
		result.put(4, "李");
		result.put(5, "周");
		result.put(6, "吴");
		result.put(7, "郑");
		result.put(8, "王");
		return result;
	}


}

